﻿using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Weight.Base.Utility
{
    /// <summary>
    /// 计算公共类
    /// </summary>
    public class CalculateHelper
    {
        /// <summary>
        /// 接受一个string类型的表达式并计算结果,返回一个object对象,静态方法 
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static object Calculate(string expression)
        {
            string className = "Calc";
            string methodName = "Run";
            expression = expression.Replace("/", "*1.0/");

            //设置编译参数
            CompilerParameters paras = new CompilerParameters();
            paras.GenerateExecutable = false;
            paras.GenerateInMemory = true;

            //创建动态代码
            StringBuilder classSource = new StringBuilder();
            classSource.Append("public class " + className + "\n");
            classSource.Append("{\n");
            classSource.Append(" public object " + methodName + "()\n");
            classSource.Append(" {\n");
            classSource.Append(" return " + expression + ";\n");
            classSource.Append(" }\n");
            classSource.Append("}");

            //编译代码
            CompilerResults result = new CSharpCodeProvider().CompileAssemblyFromSource(paras, classSource.ToString());

            //获取编译后的程序集。 
            Assembly assembly = result.CompiledAssembly;

            //动态调用方法。 
            object eval = assembly.CreateInstance(className);
            MethodInfo method = eval.GetType().GetMethod(methodName);
            object reobj = method.Invoke(eval, null);
            GC.Collect();
            return reobj;
        }
    }
}
